<template>
  <el-card class="app-container">
    <div v-if="!postionDialog">
      <div class="itemTitle">监控系统接入及电子地图展示</div>
      <div class="search">
        <el-form :inline="true" :model="queryParams" ref="queryForm">
          <el-col :span="5">
            <el-form-item label="车间" prop="workshopId">
              <el-select
                filterable
                v-model="queryParams.workshopId"
                placeholder="请选择车间"
                clearable
              >
                <el-option
                  v-for="(dict, index) in listShop"
                  :key="index"
                  :label="dict.name"
                  :value="dict.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="5">
            <el-form-item label="工房" prop="roomId">
              <el-select
                filterable
                v-model="queryParams.roomId"
                placeholder="请选择工房"
                clearable
              >
                <el-option
                  v-for="(dict, index) in listRoom"
                  :key="index"
                  :label="dict.name"
                  :value="dict.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="5">
            <el-form-item label="监控名称" prop="monitorName">
              <el-input
                @keyup.enter.native="handleQuery"
                v-model="queryParams.monitorName"
                placeholder="请输入监控名称"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="5">
            <el-form-item>
              <el-button type="primary" @click="handleQuery">搜索</el-button>
              <el-button @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-col>
        </el-form>
      </div>
      <div class="content">
        <div class="ct-btns">
          <!-- <el-button
            type="primary"
            @click="handleAddByDialog"
            v-hasPermi="['video:monitor:add']"
            >新增</el-button
          > -->
          <el-button type="primary" @click="handleSync">同步</el-button>
        </div>
        <div class="ct-table">
          <elTables
            :table-data="tableData"
            :columns="tableColumns"
            :totalLength="total"
            :currentPage="queryParams.pageNum"
            :handle-current-change="handleCurrentChange"
            isPagin
            :curHeight="tableHeight"
          />
        </div>
      </div>
    </div>
    <!-- 添加或修改视频监控对话框 -->
    <el-dialog
      :title="title"
      :visible.sync="dialogFormVisible"
      append-to-body
      @close="cancel"
      class="dialog-form"
    >
      <!-- <p class="title-level2">二级标题可选</p> -->
      <el-form ref="form" :model="form" :rules="rules" label-width="140px">
        <el-col :span="12">
          <el-form-item label="设备IP" prop="monitorIp">
            <el-input
              v-model="form.monitorIp"
              placeholder="请输入设备IP"
              :readonly="!isEdit"
              :disabled="!isEdit"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="监控名称" prop="monitorName">
            <el-input
              v-model="form.monitorName"
              placeholder="请输入监控名称"
              :readonly="!isEdit"
              :disabled="!isEdit"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="监控设备类型" prop="monitorType">
            <el-select
              v-model="form.monitorType"
              placeholder="请选择设备类型"
              :readonly="!isEdit"
              :disabled="!isEdit"
            >
              <el-option
                v-for="dict in monitorTypeList"
                :key="dict.dictValue"
                :label="dict.dictLabel"
                :value="dict.dictValue"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="车间" prop="workshopId">
            <el-select
              filterable
              v-model="form.workshopId"
              placeholder="请选择车间"
              :readonly="!isEdit"
              :disabled="!isEdit"
            >
              <el-option
                v-for="(dict, index) in listShop"
                :key="index"
                :label="dict.name"
                :value="dict.id"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="工房" prop="roomId">
            <el-select
              filterable
              v-model="form.roomId"
              placeholder="请选择工房"
              :readonly="!isEdit || (form.workshopId ? false : true)"
              :disabled="!isEdit || (form.workshopId ? false : true)"
            >
              <el-option
                v-for="(dict, index) in listRoom"
                :key="index"
                :label="dict.name"
                :value="dict.id"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="用户名" prop="userName">
            <el-input
              v-model="form.userName"
              placeholder="请输入用户名"
              :readonly="!isEdit"
              :disabled="!isEdit"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="密码" prop="password">
            <el-input
              show-password
              v-model="form.password"
              placeholder="请输入密码"
              :readonly="!isEdit"
              :disabled="!isEdit"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="播放地址" prop="mediaVideoAddress">
            <el-input
              v-model="form.mediaVideoAddress"
              placeholder="请输入播放地址"
              :readonly="!isEdit"
              :disabled="!isEdit"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="显示到大屏" prop="bigScreenSwitch">
            <el-switch
              v-model="form.bigScreenSwitch"
              :active-value="0"
              :inactive-value="1"
            >
            </el-switch>
          </el-form-item>
        </el-col>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="submitForm">确定</el-button>
      </div>
    </el-dialog>
    <!-- 导入 -->
    <el-dialog
      :title="upload.title"
      :visible.sync="upload.open"
      width="800px"
      append-to-body
    >
      <el-upload
        ref="upload"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
        <div class="el-upload__tip" style="color: red" slot="tip">
          提示：仅允许导入“xls”或“xlsx”格式文件！
        </div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFileForm">确 定</el-button>
        <el-button @click="upload.open = false">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 监空画面 -->
    <el-dialog
      title="监控画面"
      :visible.sync="videoDialog"
      @close="videoClose"
      width="800px"
      append-to-body
    >
      <!-- <video
        :src="videoUrl"
        autoplay
        width="740px"
        height="500px"
        style="object-fit: fill"
      >
      </video> -->
      <!-- <div class="video-container" style="padding: 20px; height: 540px">
        <div id="videoElement" style="width: 680px; height: 500px"></div>
      </div> -->
      <div
        class="video-container"
        style="padding: 20px; width: 740px; height: 440px"
      >
        <videoPlayer
          class="vjs-custom-skin videoPlayer"
          :options="playerOptions"
          :playsinline="true"
          ref="videoPlayer"
          @pause="onPlayerPause($event, videoItem)"
        ></videoPlayer>
      </div>
    </el-dialog>

    <div v-if="postionDialog">
      <div class="itemTitle" @click="postionDialog = false">定位</div>
      <riskMap ref="riskMap" :info="riskData" @update="updateRisk"></riskMap>
    </div>
  </el-card>
</template>

<script>
const defaultQueryParams = {
  pageNum: 1,
  pageSize: 10,
};
import { getToken } from "@/utils/auth";
import riskMap from "./riskMap.vue";
import "video.js/dist/video-js.css";
import { videoPlayer } from "vue-video-player";
import {
  pageMonitor,
  listMonitor,
  getMonitor,
  delMonitor,
  addMonitor,
  updateMonitor,
  exportMonitor,
  downImportTemplate,
  listRoom,
  listShop,
  editScreen,
  syncVideoList,
} from "@/api/video/monitor";
import WasmPlayer from "@easydarwin/easywasmplayer"; //导入WasmPlayer.js
export default {
  name: "Monitor",
  components: { riskMap, videoPlayer },
  data() {
    var validateIPAddress = (rule, value, callback) => {
      let regexp =
        /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/;
      let valdata = value.split(",");
      let isCorrect = true;
      if (valdata.length) {
        for (let i = 0; i < valdata.length; i++) {
          if (regexp.test(valdata[i]) == false) {
            isCorrect = false;
          }
        }
      }
      if (value == null || value === "") {
        callback();
      } else if (!isCorrect) {
        callback(new Error("请输入正确的IP地址"));
      } else {
        callback();
      }
    };
    return {
      videoUrl: "",
      player: null,
      tableHeight: 0,
      isEdit: false,
      dialogFormVisible: false,
      videoDialog: false, //监控画面弹窗
      postionDialog: false, //定位
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 导入参数
      upload: {
        // 是否显示弹出层（用户导入）
        open: false,
        // 弹出层标题（用户导入）
        title: "",
        // 是否禁用上传
        isUploading: false,
        // 设置上传的请求头部
        headers: { Authorization: "Bearer " + getToken() },
        // 上传的地址
        url: process.env.VUE_APP_BASE_API + "/video/monitor/importData",
      },
      tableData: [],
      listRoom: [], //工房
      listShop: [], //车间
      monitorTypeList: [], //设备类型
      // 查询参数
      queryParams: {
        ...defaultQueryParams,
        monitorName: null,
        roomId: null,
        workshopId: null,
        factoryId: null,
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        monitorName: [
          { required: true, message: "监控名称不能为空", trigger: "blur" },
        ],
        mediaVideoAddress: [
          { required: true, message: "监控播放地址不能为空", trigger: "blur" },
        ],
        monitorIp: [
          { required: true, message: "设备IP不能为空", trigger: "blur" },
          { validator: validateIPAddress, trigger: "blur" },
        ],
        userName: [
          { required: true, message: "用户名不能为空", trigger: "blur" },
        ],
        password: [
          { required: true, message: "密码不能为空", trigger: "blur" },
        ],
        workshopId: [
          {
            required: true,
            message: "车间不能为空",
            trigger: ["blur", "change"],
          },
        ],
        roomId: [
          {
            required: true,
            message: "工房不能为空",
            trigger: ["blur", "change"],
          },
        ],
        monitorType: [
          {
            required: true,
            message: "监控设备类型不能为空",
            trigger: ["blur", "change"],
          },
        ],
      },
      tableColumns: [
        { key: "monitorIp", title: "设备IP" },
        { key: "monitorName", title: "监控名称" },
        {
          key: "monitorType",
          title: "监控设备类型",
          render: (h, params) => {
            return h("div", [
              h(
                "span",
                this.selectDictLabel(
                  this.monitorTypeList,
                  params.row.monitorType
                )
              ),
            ]);
          },
        },
        { key: "workShopName", title: "车间" },
        { key: "workShopRoomName", title: "工房" },
        { key: "mediaVideoAddress", title: "播放地址" },
        {
          title: "显示到大屏",
          width: "100",
          key: "bigScreenSwitch",
          render: (h, params) => {
            return h("div", [
              h("el-switch", {
                props: {
                  value: params.row.bigScreenSwitch == 0 ? true : false,
                },
                on: {
                  change: () => {
                    this.handleStatusChange(params.row);
                  },
                },
              }),
            ]);
          },
        },
        { key: "createTime", title: "创建时间" },
        {
          title: "操作",
          align: "center",
          fixed: "right",
          width: 240,
          render: (h, params) => {
            return h("div", [
              h(
                "el-button",
                {
                  props: {
                    type: "text",
                    size: "small",
                  },
                  directives: [
                    {
                      name: "hasPermi",
                      value: ["video:monitor:info"],
                    },
                  ],
                  on: {
                    click: () => {
                      this.lookVideo(params.row);
                    },
                  },
                },
                "监控画面"
              ),
              h(
                "el-button",
                {
                  props: {
                    type: "text",
                    size: "small",
                  },
                  directives: [
                    {
                      name: "hasPermi",
                      value: ["video:monitor:info"],
                    },
                  ],
                  on: {
                    click: () => {
                      this.position(params.row);
                    },
                  },
                },
                "定位"
              ),
              h(
                "el-button",
                {
                  props: {
                    type: "text",
                    size: "small",
                  },
                  directives: [
                    {
                      name: "hasPermi",
                      value: ["video:monitor:edit"],
                    },
                  ],
                  on: {
                    click: () => {
                      this.handleUpdate(params.row, 1);
                    },
                  },
                },
                "编辑"
              ),
              h(
                "el-button",
                {
                  props: {
                    type: "text",
                    size: "small",
                  },
                  directives: [
                    {
                      name: "hasPermi",
                      value: ["video:monitor:remove"],
                    },
                  ],
                  on: {
                    click: () => {
                      this.handleDelete(params.row);
                    },
                  },
                },
                "删除"
              ),
            ]);
          },
        },
      ],
      riskData: {}, //定位信息
      player: null,
      playerOptions: {},
    };
  },
  created() {
    this.getPage();
    this.getlistShop();
    this.getlistRoom();
    this.getDicts("monitor_type").then((response) => {
      this.monitorTypeList = response.data;
    });
  },
  mounted() {
    this.$nextTick(() => {
      this.getTableHeight();
    });
  },
  watch: {
    "queryParams.workshopId": {
      handler(newVal, oldVal) {
        // console.log(newVal, oldVal, "车间发生变化");
        if (newVal !== oldVal) {
          // 获取工房
          this.getlistRoom(newVal);
        }
      },
      deep: true,
    },
    "form.workshopId": {
      handler(newVal, oldVal) {
        if (newVal !== oldVal) {
          // 获取工房
          this.getlistRoom(newVal);
        }
      },
      deep: true,
    },
  },
  methods: {
    play(url) {
      this.player = new WasmPlayer(null, "videoElement", this.callbackfun, {
        decodeType: "auto", //解码类型(auto：默认，soft：强制H265解码)
        Height: true, //播放器尺寸是否继承父盒子的
        fluent: true,
        HideKbs: true,
      });
      // 调用播放
      this.player.play(url, 1);
    },
    videoClose() {
      this.$refs.videoPlayer.player.pause();
      this.videoDialog = false;
    },
    //同步视频接口
    handleSync() {
      syncVideoList().then((res) => {
        console.log(res);
        //同步之后刷新列表
        this.getPage();
      });
    },
    // 编辑修改地图信息
    updateRisk(val) {
      if (val.locateInfo) {
        val.locateInfo = JSON.stringify(val.locateInfo);
        this.postionDialog = false;
        updateMonitor(val).then((response) => {
          this.msgSuccess("修改成功");
          this.dialogFormVisible = false;
          this.getPage();
        });
      } else {
        this.$message.warning("请先选择摄像图位置");
      }
    },
    //监控画面
    lookVideo(row) {
      this.videoDialog = true;
      // this.videoUrl = "http://114.67.235.28:17002/sanwo01/001.live.mp4";
      this.$nextTick(() => {
        this.playerOptions = {
          playbackRates: [0.5, 1.0, 1.5, 2.0], // 可选的播放速度
          autoplay: true, // 如果为true,浏览器准备好时开始回放。
          muted: false, // 默认情况下将会消除任何音频。
          loop: false, // 是否视频一结束就重新开始。
          live: true,
          language: "zh-CN",
          aspectRatio: "16:9", // 将播放器置于流畅模式，并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字（例如"16:9"或"4:3"）
          fluid: true, // 当true时，Video.js player将拥有流体大小。换句话说，它将按比例缩放以适应其容器。
          sources: [
            {
              type: "video/mp4", // 类型
              src: row.mediaVideoAddress, // url地址 row.mediaVideoAddress
            },
          ],
          notSupportedMessage: "此视频暂无法播放，请稍后再试", // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
        };
      });
    },
    onPlayerPause() {},
    // 定位
    position(row) {
      getMonitor(row.monitorId).then((response) => {
        this.riskData = response.data;
        if (response.data.locateInfo) {
          this.$nextTick(() => {
            this.$refs.riskMap.addPoints(JSON.parse(response.data.locateInfo));
            setTimeout(() => {
              this.$refs.riskMap.loading = false;
            }, 5000);
          });
        }
      });
      this.postionDialog = true;
    },
    /** 下载模板操作 */
    importTemplate() {
      downImportTemplate().then((response) => {
        this.download(response.msg);
      });
    },
    //大屏开关
    handleStatusChange(row) {
      let text = row.bigScreenSwitch == 0 ? "停用" : "启用";
      let obj = JSON.parse(JSON.stringify(row));
      let that = this;
      this.$modal
        .confirm("确认要" + text + "吗？")
        .then(function () {
          obj.bigScreenSwitch = row.bigScreenSwitch == "1" ? "0" : "1";
          return editScreen({
            monitorId: obj.monitorId,
            bigScreenSwitch: obj.bigScreenSwitch,
          });
        })
        .then(() => {
          that.$modal.msgSuccess("操作成功");
          that.getPage();
        })
        .catch(function () {
          that.getPage();
        });
    },
    //获取工房
    getlistRoom(val) {
      let q = { workShopId: val };
      listRoom(q).then((res) => {
        this.listRoom = res.data;
      });
    },
    //获取车间
    getlistShop() {
      listShop().then((res) => {
        this.listShop = res.data;
      });
    },
    handleAddByDialog() {
      this.dialogFormVisible = true;
      this.title = "新增监控设备";
      this.reset();
      this.isEdit = true;
    },
    getTableHeight() {
      let height = document.getElementsByClassName("ct-table")[0].clientHeight;
      this.tableHeight = height - 40;
    },
    handleCurrentChange(val) {
      this.queryParams.pageNum = val;
      this.getPage();
    },
    /** 查询视频监控列表 */
    getPage() {
      this.loading = true;
      pageMonitor(this.queryParams).then((response) => {
        this.tableData = response.data.records;
        this.total = response.data.total;
        this.loading = false;
      });
    },
    // 取消按钮
    cancel() {
      this.dialogFormVisible = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        monitorId: null,
        monitorName: null,
        monitorIp: null,
        userName: null,
        password: null,
        areaId: null,
        monitorType: null,
        remark: null,
        mediaVideoAddress: null,
        mediaVideoAddressHot: null,
        rtspVideoAddress: null,
        locateInfo: null,
        factoryId: null,
        createBy: null,
        createTime: null,
        updateBy: null,
        updateTime: null,
        createDept: null,
        delFlag: null,
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getPage();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      console.log(selection);
      this.ids = selection.map((item) => item.monitorId);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    /** 修改按钮操作 */
    handleUpdate(row, type) {
      if (type == 1) {
        this.isEdit = true;
      } else {
        this.isEdit = false;
      }
      this.reset();
      const monitorId = row.monitorId || this.ids;
      getMonitor(monitorId).then((response) => {
        this.form = response.data;
        this.form.bigScreenSwitch = this.form.bigScreenSwitch * 1;
        this.dialogFormVisible = true;
        this.title = "编辑视频监控";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          if (this.form.monitorId != null) {
            updateMonitor(this.form).then((response) => {
              this.msgSuccess("修改成功");
              this.dialogFormVisible = false;
              this.getPage();
            });
          } else {
            addMonitor(this.form).then((response) => {
              this.msgSuccess("新增成功");
              this.dialogFormVisible = false;
              this.getPage();
            });
          }
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const monitorIds = row.monitorId || this.ids;
      this.$confirm("是否确认删除?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(function () {
          let data;
          if (Array.isArray(monitorIds)) {
            data = monitorIds;
          } else {
            data = [monitorIds];
          }
          return delMonitor(data);
        })
        .then(() => {
          this.getPage();
          this.msgSuccess("删除成功");
        });
    },
    /** 导出按钮操作 */
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm("是否确认导出所有视频监控数据项?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(function () {
          return exportMonitor(queryParams);
        })
        .then((response) => {
          this.download(response.msg);
        });
    },
    /** 导入按钮操作 */
    handleImport() {
      this.upload.title = "导入";
      this.upload.open = true;
    },
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true;
    },
    // 文件上传成功处理
    handleFileSuccess(response, file, fileList) {
      this.upload.open = false;
      this.upload.isUploading = false;
      this.$refs.upload.clearFiles();
      this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
      this.getPage();
    },
    // 提交导入文件
    submitFileForm() {
      this.$refs.upload.submit();
    },
  },
};
</script>
<style lang="scss" scoped>
.video-container {
  width: 100%;
  height: 0;
  padding-bottom: 56.25%; // 用于16:9的视频比例，可根据实际情况调整
}
</style>
